#ifndef NETWORK_MANAGER_H
#define NETWORK_MANAGER_H

#include <QMap>
#include <QList>
#include <QObject>
#include <QSemaphore>
#include <QVariant>


class QNetworkAccessManager;
namespace Network {
class Connection;
class Request;
class Parser;
class Event;

struct Endpoint{
    Endpoint(){}
    Endpoint(QString s, QString h, int p)
        :scheme(s)
        ,host(h)
        ,port(p)
    {

    }

    QString scheme;
    QString host;
    int port;
};

class Manager : public QObject
{
    Q_OBJECT
protected:
    Manager(QObject *parent = 0);

public:
    static Manager *instance(QObject *parent = 0);

    //    inline static void setServer(const QString &server) {
    //        m_server = server;
    //    }

    //    inline static const QString &server() {
    //        return m_server;
    //    }

    //    inline static void setPort(int port) {
    //        m_port = port;
    //    }

    inline static int port() {
        return m_port;
    }

public:
    inline QNetworkAccessManager &manager() {
        return *m_manager;
    }

    inline Connection &connection() {
        return *m_connection;
    }

    inline const QString &sessionKey() const {
        return m_sessionKey;
    }

    inline QThread *worker() {
        return m_worker;
    }

public:
    bool post(Request *request);
    void stop();

signals:
    void connected();
    void received(const QString &commandId, const QVariant &data);
    void disconnected();
    void sessionKeyReady();


private slots:

    void onConnected();
    void onReceived(QByteArray message);
    void onDisconnected();
public slots:
    void onLogined(bool successed, const QString &message, const QString &sessionKey);
    void onLogouted();
    void reconnect();

private:
    virtual QVariant params() const = 0;
    void logout();
private:
    bool getNextEndpoint(Endpoint& endpoint);

private:
    Connection *m_connection;
    QNetworkAccessManager *m_manager;
    QThread *m_worker;
    QString m_sessionKey;

private:
    static Manager *m_instance;
    static QString m_server;
    static int m_port;
protected :
    bool m_wantDisconnect;
    QList<Endpoint> m_serverEnpoints;
};

} // namespace Network
#endif // NETWORK_MANAGER_H
